class Sale < ActiveRecord::Base
  has_paper_trail meta: { explain: :change_explain }

  attr_accessor :change_explain

  belongs_to :staff, class_name: User, foreign_key: :user_id
  belongs_to :customer
  belongs_to :product

  belongs_to :product_version, class_name: PaperTrail::Version

  scope :month, -> (month) { where(sold_at: month.beginning_of_month..month.end_of_month) }

  validates :sold_at, presence: true
  validate :product_sale_duration

  before_save :set_sale_reward
  before_save :set_expired_date
  before_save :set_product_version

  # 员工月度奖励
  def self.staff_month_reward(staff_id, month)
    Sale.month(month).where(user_id: staff_id).sum(:sales_reward)
  end

  def solid_product
    return product unless product_version
    return product_version.next.reify if product_version.next

    product
  end

  private
  def product_sale_duration
    sale_start_at, sale_end_at = solid_product.sale_start_at, solid_product.sale_end_at

    if sale_start_at && sale_end_at
      errors.add(:base, "此产品目前不在销售时段") unless self.sold_at.between?(sale_start_at, sale_end_at)
    elsif sale_start_at
      errors.add(:base, "此产品目前不在销售时段") if self.sold_at < sale_start_at
    elsif sale_end_at
      errors.add(:base, "此产品目前不在销售时段") if self.sold_at > sale_end_at
    end
  end

  def set_sale_reward
    return unless self.product_id_changed? || self.product_number_changed?

    self.sales_reward = (self.solid_product.reward / 100) * self.solid_product.price * self.product_number
  end

  # 计算到期时间
  def set_expired_date
    return unless self.sold_at_changed?

    self.product_expired_at = case self.product.validity_type
      when 'forever' then nil
      when 'day' then self.sold_at + self.product.validity_duration.days
      when 'month' then self.sold_at + self.product.validity_duration.months
      end
  end

  def set_product_version
    return unless self.product_id_changed?

    self.product_version_id = self.product.versions.last.id
  end
end
